﻿using UnityEngine;
using System.Collections;
using System.Net;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Security.Cryptography;
using System.Text;
using System.Text.RegularExpressions;

namespace ZWFrameWork
{

    public class ProtoAttribute : Attribute
    {
        public int SizeConst;
        public UnmanagedType unmanagedType;
        public UnmanagedType ArraySubType;
        public ProtoAttribute(UnmanagedType unmanagedType)
        {
            this.unmanagedType = unmanagedType;
        }
    }

    public class MyTypeAttribute : Attribute
    {
        public MyTypeAttribute(int pet)
        {
            thePet = pet;
        }

        protected int thePet;

        public int Pet
        {
            get { return thePet; }
            set { thePet = Pet; }
        }
    }


    /// <summary>
    /// 网络层工具类 
    /// </summary>
    public class NetUtils
    {
        public static byte[] UTF8ToUTF16(string utf8string, int backLength)
        {
            // if (string.IsNullOrEmpty(utf8string) || string.IsNullOrWhiteSpace(utf8string))
            // {
            //     Debug.LogError("utf8string is null or empty");
            //     return null;
            // }

            byte[] key = new byte[backLength];
            byte[] bytearray_unicode = Encoding.Unicode.GetBytes(utf8string);
            int count = 0;
            int length = bytearray_unicode.Length;
            int returnlength = backLength >= length ? length : backLength;
            for (int i = 0; i < returnlength; i++)
            {
                key[i] = bytearray_unicode[i];
                count++;
            }

            return key;
        }
        /// <summary>
        /// 保存的结构体的长度
        /// </summary>
        private static Dictionary<string, int> DicStructLength = new Dictionary<string, int>();
        /// <summary>
        /// 将16进制字节转换为string
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        public static string UTF16ByteArrayToString(byte[] data)
        {
            if (data == null)
            {
                Debug.LogError("data is null!");
                return "";
            }

            byte[] utf8Bytes = Encoding.Convert(Encoding.Unicode, Encoding.UTF8, data);
            return ByteArrayToString(utf8Bytes);
        }

        /// <summary>
        /// 将字节数组转换为string
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        public static string ByteArrayToString(byte[] data)
        {
            if (data == null)
            {
                Debug.LogError("data is null!");
                return "";
            }

            return System.Text.Encoding.UTF8.GetString(data).Trim('\0').Trim();
        }


        /// <summary>
        /// 去掉byte数组前面size长度返回,主要用于解析去除包头用
        /// </summary>
        /// <param name="mainData">MainData</param>
        /// <param name="size">去除长度</param>
        /// <returns></returns>
        public static byte[] GetRidOfFrontBytes(byte[] mainData, int size)
        {
            int length = mainData.Length;
            if (length <= size)
                return null;
            byte[] data = new byte[length - size];
            Array.Copy(mainData, size, data, 0, length - size);
            //for (int i = size; i < length; i++)
            //data[i - size] = mainData[i];
            return data;
        }

        /// <summary>
        /// 通过字符串获取MD5值，返回32位字符串。
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static string GetMD5String(string str)
        {
            MD5 md5 = MD5.Create();
            byte[] data = Encoding.UTF8.GetBytes(str);
            byte[] data2 = md5.ComputeHash(data);

            return GetbyteToString(data2);
        }


        /// <summary>
        /// 将byte数组转换成string
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        private static string GetbyteToString(byte[] data)
        {
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < data.Length; i++)
            {
                sb.Append(data[i].ToString("x2"));
            }

            return sb.ToString();
        }

        /// <summary>
        /// 加密byte
        /// </summary>
        /// <returns></returns>
        public static byte[] EncodeByte(byte[] buffer)
        {
            //加密
            try
            {
                int nOutputLen = buffer.Length;
                byte[] pOutputBuffer = new byte[nOutputLen];
                if (Encrypt.encode(buffer, ref pOutputBuffer, (ushort)nOutputLen))
                {
                    Debug.Log("加密成功!数据长度为:" + pOutputBuffer.Length);
                }

                if (nOutputLen != pOutputBuffer.Length)
                {
                    Debug.LogError("发送数据异常!");
                    return null;
                }

                return pOutputBuffer;
            }
            catch (Exception ex)
            {
                Debug.LogError("WebSocketZ:" + ex.ToString());
                return null;
            }
        }

        ///// <summary>
        ///// StructToBytes
        ///// </summary>
        ///// <param name="structure"></param>
        ///// <returns></returns>
        //public static byte[] StructToBytes1(object structure)
        //{
        //    Int32 size = Marshal.SizeOf(structure);
        //    IntPtr buffer = Marshal.AllocHGlobal(size);
        //    try
        //    {
        //        Marshal.StructureToPtr(structure, buffer, false);
        //        byte[] bytes = new byte[size];
        //        Marshal.Copy(buffer, bytes, 0, size);
        //        return bytes;
        //    }
        //    finally
        //    {
        //        Marshal.FreeHGlobal(buffer);
        //    }
        //}
        /// <summary>
        /// 结构体转byte数组
        /// </summary>
        /// <param name="structObj"></param>
        /// <returns></returns>
        public static byte[] StructToBytes(object obj)
        {
            try
            {
                
                byte[] des = new byte[2048];
                int start = 0;
                Type type = obj.GetType();

                FieldInfo[] myfields = type.GetFields();
             
                for (int i = 0; i < myfields.Length; i++)
                {
           
                    FieldInfo fi = myfields[i];
                    Type t = fi.FieldType;
                    byte[] sou;
                    switch (t.Name)
                    {
                        case "int":
                        case "Int32":
                            {
                                sou = BitConverter.GetBytes((Int32)type.GetField(fi.Name).GetValue(obj));
                                break;
                            }
                        case "UInt32":
                            {
                                sou = BitConverter.GetBytes((UInt32)type.GetField(fi.Name).GetValue(obj));
                                break;
                            }
                        case "byte":
                        case "Byte":
                            {
                                sou = new byte[1];
                                sou[0] = (byte)type.GetField(fi.Name).GetValue(obj);
                                break;
                            }
                        case "Boolean":
                            {
                                sou = BitConverter.GetBytes((Boolean)type.GetField(fi.Name).GetValue(obj));
                                break;
                            }
                        case "Int16":
                            {
                                sou = BitConverter.GetBytes((Int16)type.GetField(fi.Name).GetValue(obj));
                                break;
                            }
                        case "UInt16":
                            {
                                sou = BitConverter.GetBytes((UInt16)type.GetField(fi.Name).GetValue(obj));
                                break;
                            }
                        case "Int64":
                            {
                                sou = BitConverter.GetBytes((Int64)type.GetField(fi.Name).GetValue(obj));
                                break;
                            }
                        case "String":
                        case "string":
                            {
                                int length = fi.GetCustomAttribute<ProtoAttribute>().SizeConst * ss;
                                byte[] source = Encoding.Unicode.GetBytes((string)type.GetField(fi.Name).GetValue(obj));
                                sou = new byte[length];
                                int len = length;
                                if (source.Length<len)
                                {
                                    len = source.Length;
                                }
                                Array.Copy(source, sou, len);
                                
                                //sou = BitConverter.GetBytes((string)type.GetField(fi.Name).GetValue(obj));
                                break;
                            }
                        case "Double":
                            {
                                
                                sou = BitConverter.GetBytes((Double)type.GetField(fi.Name).GetValue(obj));
                                break;
                            }
                        case "Byte[]":
                            {

                                byte[] bytes = (byte[])type.GetField(fi.Name).GetValue(obj);
                                sou = bytes;
                                break;
                            }
                        case "Int32[]":
                            {
                                int[] ints = (int[])type.GetField(fi.Name).GetValue(obj);
                                byte[] intByteTemp = new byte[ints.Length * 4];
                                int tempStart = 0;
                                for (int j = 0; j < ints.Length; j++)
                                {
                                    byte[] temp = BitConverter.GetBytes(ints[j]);

                                    MemCpy(intByteTemp, temp, tempStart);
                                    tempStart += 4;
                                }
                                sou = intByteTemp;
                                break;
                            }
                        case "UInt32[]":
                            {
                                uint[] ints = (uint[])type.GetField(fi.Name).GetValue(obj);
                                byte[] intByteTemp = new byte[ints.Length * 4];
                                int tempStart = 0;
                                for (int j = 0; j < ints.Length; j++)
                                {
                                    byte[] temp = BitConverter.GetBytes(ints[j]);

                                    MemCpy(intByteTemp, temp, tempStart);
                                    tempStart += 4;
                                }
                                sou = intByteTemp;
                                break;
                            }
                        case "Int64[]":
                            {
                                Int64[] ints = (Int64[])type.GetField(fi.Name).GetValue(obj);
                                byte[] intByteTemp = new byte[ints.Length * 8];
                                int tempStart = 0;
                                for (int j = 0; j < ints.Length; j++)
                                {
                                    byte[] temp = BitConverter.GetBytes(ints[j]);

                                    MemCpy(intByteTemp, temp, tempStart);
                                    tempStart += 8;
                                }
                                sou = intByteTemp;
                                break;
                            }
                        case "Double[]":
                            {
                                Double[] ints = (Double[])type.GetField(fi.Name).GetValue(obj);
                                byte[] intByteTemp = new byte[ints.Length * 8];
                                int tempStart = 0;
                                for (int j = 0; j < ints.Length; j++)
                                {
                                    byte[] temp = BitConverter.GetBytes(ints[j]);
                                    MemCpy(intByteTemp, temp, tempStart);
                                    tempStart += 8;
                                }
                                sou = intByteTemp;
                                break;
                            }
                        case "UInt64[]":
                            {
                                UInt64[] ints = (UInt64[])type.GetField(fi.Name).GetValue(obj);
                                byte[] intByteTemp = new byte[ints.Length * 8];
                                int tempStart = 0;
                                for (int j = 0; j < ints.Length; j++)
                                {
                                    byte[] temp = BitConverter.GetBytes(ints[j]);

                                    MemCpy(intByteTemp, temp, tempStart);
                                    tempStart += 8;
                                }
                                sou = intByteTemp;
                                break;
                            }

                        case "Int16[]":
                            {
                                short[] ints = (short[])type.GetField(fi.Name).GetValue(obj);
                                byte[] intByteTemp = new byte[ints.Length * 2];
                                int tempStart = 0;
                                for (int j = 0; j < ints.Length; j++)
                                {
                                    byte[] temp = BitConverter.GetBytes(ints[j]);
                                    MemCpy(intByteTemp, temp, tempStart);
                                    tempStart += 2;
                                }
                                sou = intByteTemp;
                                break;
                            }
                        case "UInt16[]":
                            {
                                ushort[] ints = (ushort[])type.GetField(fi.Name).GetValue(obj);
                                byte[] intByteTemp = new byte[ints.Length * 2];
                                int tempStart = 0;
                                for (int j = 0; j < ints.Length; j++)
                                {
                                    byte[] temp = BitConverter.GetBytes(ints[j]);

                                    MemCpy(intByteTemp, temp, tempStart);
                                    tempStart += 2;
                                }
                                sou = intByteTemp;
                                break;
                            }
                        default:
                            {
                                if (!t.IsPrimitive)
                                {
                                    //数组
                                    if (t.HasElementType)
                                    {
                                        Debug.LogError("打包错误！！！不能够使用结构体数组  type.Name:" + type.Name);
                                        sou = new byte[1];
                                    }
                                    else
                                    {
                                        sou = StructToBytes(type.GetField(fi.Name).GetValue(obj));
                                    }
                                }
                                else
                                {
                                    Debug.LogError(" 打包错误！！！！   type.Name:" + type.Name);
                                    sou = new byte[1];
                                }
                                break;
                            }
                    }
                    MemCpy(des, sou, start);
                    start += sou.Length;
                }

                byte[] byteData = new byte[start];
                Array.Copy(des, byteData, byteData.Length);
                return byteData;
            }
            catch(Exception ex)
            {
                Debug.LogError("zzzzzzz:" + ex.StackTrace +" T:"+obj.GetType().Name);
                Debug.LogError("zzzzzzz:"+ex.Message);
            }

            return null;
        }

        public static void MemCpy(byte[] des, byte[] sou, int start)
        {
            for (int a = 0; a < sou.Length; ++a)
            {
                des[start + a] = sou[a];
            }
        }

        public static void MemCpy(byte[] des, byte[] sou, int start, int length)
        {
            for (int a = 0; a < length; ++a)
            {
                des[start + a] = sou[a];
            }
        }

        public static void MemCpy(byte[] des, byte[] sou, int start1, int start2, int length)
        {
            if (des.Length - start1 < length || sou.Length - start2 < length)
            {
                return;
            }
            for (int a = 0; a < length; ++a)
            {
                des[start1 + a] = sou[start2 + a];
            }
        }
        /// <summary>
        /// bytesToStructNew
        /// </summary>
        /// <param name="bytes"></param>
        /// <returns></returns>
        //public static T bytesToStruct<T>(byte[] bytes)
        //{
        //    Debug.LogError("zzzzzz:" + bytes.Length + ",zz:" + typeof(T).Name);
        //    Int32 struct_size = Marshal.SizeOf(typeof(T));
        //    int mallocSize = 0;
        //    if (bytes.Length >= struct_size)
        //    {
        //        mallocSize = struct_size;
        //    }
        //    else
        //    {
        //        // Debug.Log("<color=#4B0082>包</color><color=#FF00FF>[" + typeof(T).Name + "]</color>" +
        //        // "<color=#4B0082>收到字节长度" + bytes.Length + ",结构体长度=" + struct_size + ",暂时可忽略</color>");
        //        mallocSize = bytes.Length;
        //    }

        //    IntPtr buffer = Marshal.AllocHGlobal(mallocSize);
        //    try
        //    {
        //        Marshal.Copy(bytes, 0, buffer, mallocSize);
        //        return Marshal.PtrToStructure<T>(buffer);
        //    }
        //    finally
        //    {
        //        Marshal.FreeHGlobal(buffer);
        //    }
        //}
        public static T bytesToStruct<T>(byte[] receiveData)
        {
            return (T)bytesToStruct(receiveData, typeof(T));
        }
        /// <summary>
        /// byte数组转结构体
        /// </summary>
        /// <param name="receiveData"></param>
        /// <param name="type"></param>
        public static object bytesToStruct(byte[] receiveData, Type type)
        {
            //Debug.LogError("zzzzzz:" + receiveData.Length + "zz:" + type.Name);
            object obj = Activator.CreateInstance(type);
            int start = 0;
            //Debug.LogError("zzzzzzzzzzzzzzz:" + type.ToString());
            try
            {
                FieldInfo[] myfields = type.GetFields();
                for (int i = 0; i < myfields.Length; i++)
                {
                    FieldInfo fi = myfields[i];
                    Type t = fi.FieldType;
                    object fieldValue;
                    //Debug.LogError(t.Name);
                    switch (t.Name)
                    {
                        case "int":
                        case "Int32":
                            {
                                fieldValue = BitConverter.ToInt32(receiveData, start);
                                start += 4;
                                type.GetField(fi.Name).SetValue(obj, fieldValue);
                                break;
                            }
                        case "UInt32":
                            {
                                fieldValue = BitConverter.ToUInt32(receiveData, start);
                                start += 4;
                                type.GetField(fi.Name).SetValue(obj, fieldValue);
                                break;
                            }
                        case "byte":
                        case "Byte":
                            {
                                fieldValue = receiveData[start];
                                start += 1;
                                type.GetField(fi.Name).SetValue(obj, fieldValue);
                                break;
                            }
                        case "Boolean":
                            {
                                fieldValue = BitConverter.ToBoolean(receiveData, start);
                                start += 1;
                                type.GetField(fi.Name).SetValue(obj, fieldValue);
                                break;
                            }
                        case "Int16":
                            {
                                fieldValue = BitConverter.ToInt16(receiveData, start);
                                start += 2;
                                type.GetField(fi.Name).SetValue(obj, fieldValue);
                                break;
                            }
                        case "UInt16":
                            {
                                fieldValue = BitConverter.ToUInt16(receiveData, start);
                                start += 2;
                                type.GetField(fi.Name).SetValue(obj, fieldValue);
                                break;
                            }
                        case "long":
                        case "Int64":
                            {
                                fieldValue = BitConverter.ToInt64(receiveData, start);
                                start += 8;
                                type.GetField(fi.Name).SetValue(obj, fieldValue);
                                break;
                            }
                        case "byte[]":
                        case "Byte[]":
                            {
                                int length = GetArrayLengthByAttribute(fi);
                                byte[] byteString = new byte[length];
                                for (int j = 0; j < length; j++)
                                {
                                    if (receiveData.Length > start)
                                    {
                                        byteString[j] = receiveData[start];
                                        start += 1;
                                    }
                                }
                                type.GetField(fi.Name).SetValue(obj, byteString);
                                break;
                            }
                        case "Int32[]":
                            {
                                int length = GetArrayLengthByAttribute(fi);
                                int[] ints = new int[length];
                                for (int j = 0; j < length; j++)
                                {
                                    ints[j] = BitConverter.ToInt32(receiveData, start);
                                    start += 4;
                                }
                                type.GetField(fi.Name).SetValue(obj, ints);
                                break;
                            }
                        case "UInt32[]":
                            {
                                int length = GetArrayLengthByAttribute(fi);
                                uint[] ints = new uint[length];
                                for (int j = 0; j < length; j++)
                                {
                                    ints[j] = BitConverter.ToUInt32(receiveData, start);
                                    start += 4;
                                }
                                type.GetField(fi.Name).SetValue(obj, ints);
                                break;
                            }
                        case "Int16[]":
                            {
                                int length = GetArrayLengthByAttribute(fi);
                                short[] ints = new short[length];
                                for (int j = 0; j < length; j++)
                                {
                                    ints[j] = BitConverter.ToInt16(receiveData, start);
                                    start += 2;
                                }
                                type.GetField(fi.Name).SetValue(obj, ints);
                                break;
                            }
                        case "UInt16[]":
                            {
                                int length = GetArrayLengthByAttribute(fi);
                                ushort[] ints = new ushort[length];
                                for (int j = 0; j < length; j++)
                                {
                                    ints[j] = BitConverter.ToUInt16(receiveData, start);
                                    start += 2;
                                }
                                type.GetField(fi.Name).SetValue(obj, ints);
                                break;
                            }

                        case "Int64[]":
                            {
                                int length = GetArrayLengthByAttribute(fi);
                                Int64[] ints = new Int64[length];
                                for (int j = 0; j < length; j++)
                                {
                                    ints[j] = BitConverter.ToInt64(receiveData, start);
                                    start += 8;
                                }
                                type.GetField(fi.Name).SetValue(obj, ints);
                                break;
                            }
                        case "String":
                        case "string":
                            {
                                int length = fi.GetCustomAttribute<ProtoAttribute>().SizeConst*ss;
                                //Debug.LogError("zssssssssss:" + length+" Start:"+start+" zzz:"+ receiveData.Length);
                                string str = Encoding.Unicode.GetString(receiveData, start, length);
                                //Debug.LogError($"str:{str}");
                                //string str =  BitConverter.ToString(receiveData, start, length);
                                start += length;
                                type.GetField(fi.Name).SetValue(obj, str);
                                break;
                            }
                        case "double":
                        case "Double"://新添加，原来无此类型
                            {
                                fieldValue = BitConverter.ToDouble(receiveData, start);
                                start += 8;
                                type.GetField(fi.Name).SetValue(obj, fieldValue);
                                break;
                            }
                        case "double[]"://新添加，原来无此类型
                        case "Double[]"://新添加，原来无此类型
                            {
                                int length = GetArrayLengthByAttribute(fi);
                                Double[] ints = new Double[length];
                                for (int j = 0; j < length; j++)
                                {
                                    ints[j] = BitConverter.ToDouble(receiveData, start);
                                    start += 8;
                                }
                                type.GetField(fi.Name).SetValue(obj, ints);
                                break;
                            }
                        default:
                            {
                                //其它的结构体类型
                                if (!t.IsPrimitive)
                                {
                                    int structLength = 0;
                                    if (t.HasElementType) //数组类型的
                                    {
                                        //根据属性获取数组的长度
                                        int arrayLength = GetArrayLengthByAttribute(fi);

                                        object objectValue = null;
                                        if (t.GetElementType().Name.Equals("BYTE_5"))
                                        {
                                            //objectValue = GetStructValue<BYTE_5>(arrayLength, t.GetElementType(), ref start, receiveData);
                                        }
                                        else if (t.GetElementType().Name.Equals("tagFishBaseCfgItem"))
                                        {
                                            //objectValue = GetStructValue<tagFishBaseCfgItem>(arrayLength, t.GetElementType(), ref start, receiveData);
                                        }
                                        // else if (t.GetElementType().Name.Equals("Pieces"))
                                        // {
                                        //     objectValue = GetStructValue<NS_GAME_250.Pieces>(arrayLength, t.GetElementType(), ref start, receiveData);
                                        // }
                                        

                                        //else if (t.GetElementType().Name.Equals("MSG_VIP_INFO_DATA_ITEM"))
                                        //{
                                        //objectValue = GetStructValue<MSG_VIP_INFO_DATA_ITEM>(arrayLength, t.GetElementType(), ref start, receiveData);
                                        //}
                                        else if (t.GetElementType().Name.Equals("RecordIterm"))
                                        {
                                            //objectValue = GetStructValue<RecordIterm>(arrayLength, t.GetElementType(), ref start, receiveData);
                                        }
                                        else
                                        {
                                            //objectValue = null;
                                            Debug.LogError(" eDataParse解析包的时候错误！！  Name:" + t.GetElementType().Name);
                                        }

                                        type.GetField(fi.Name).SetValue(obj, objectValue);
                                    }
                                    else
                                    {
                                        //fieldValue = BitConverter.ToInt16(receiveData, start);
                                        structLength = GetStructLength(t);

                                        byte[] structData = new byte[structLength];
                                        // Debug.LogError($"receiveData:{receiveData.Length},start:{start},structLength:{structLength},zz:{t.Name},type：{type}");
                                        Array.Copy(receiveData, start, structData, 0, structLength);

                                        fieldValue = bytesToStruct(structData, t);

                                        start += structLength;
                                        type.GetField(fi.Name).SetValue(obj, fieldValue);
                                    }
                                }
                                else
                                {
                                    Debug.LogError(" eDataParse解析包的时候错误！！");
                                    return null;
                                }
                                break;
                            }
                    }
                }
            }
            catch (Exception ex)
            {
                Debug.LogError(ex.StackTrace);
                Debug.LogError(" eDataParse解析包的时候错误！！  Name:" + type.Name + "  ex:" + ex.ToString());
            }
           
            return obj;
        }
        /// <summary>
        /// 获取结构体的大小
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public static int GetStructLength<T>()
        {
            return GetStructLength(typeof(T));
        }
        public static int ss = 2;
        /// <summary>
        /// 获取结构体的大小
        /// </summary>
        /// <param name="type"></param>
        /// <returns></returns>
        public static int GetStructLength(Type type)
        {
            int length = 0;
            //如果已经保存有结构体长度的值，则直接取保存里的值
            if (DicStructLength.ContainsKey(type.FullName))
            {
                return DicStructLength[type.FullName];
            }

            FieldInfo[] myfields = type.GetFields();

            for (int i = 0; i < myfields.Length; i++)
            {
                FieldInfo fi = myfields[i];
                Type fieldType = fi.FieldType;

                switch (fieldType.Name)
                {
                    case "Int32":
                    case "UInt32":
                        {
                            length += 4;
                            break;
                        }
                    case "Boolean":
                    case "byte":
                    case "Byte":
                        {
                            length += 1;
                            break;
                        }
                    case "Int16":
                    case "UInt16":
                        {
                            length += 2;
                            break;
                        }
                    case "double":
                    case "Double":
                    case "Int64":
                    case "UInt64":
                        {
                            length += 8;
                            break;
                        }
                    case "byte[]":
                    case "Byte[]":
                        {
                            int byteTemp = GetArrayLengthByAttribute(fi);
                            length += byteTemp;
                            break;
                        }
                    case "Int32[]":
                    case "UInt32[]":
                        {
                            int intTemp = GetArrayLengthByAttribute(fi);
                            length += intTemp * 4;
                            break;
                        }
                    case "Int64[]":
                    case "UInt64[]":
                        {
                            int intTemp = GetArrayLengthByAttribute(fi);
                            length += intTemp * 8;
                            break;
                        }
                    case "Int16[]":
                    case "UInt16[]":
                        {
                            int intTemp = GetArrayLengthByAttribute(fi);
                            length += intTemp * 2;
                            break;
                        }
                    case "string":
                    case "String":
                        {
                         
                            int intTemp = fi.GetCustomAttribute<ProtoAttribute>().SizeConst * ss;
                            length += intTemp;
                            break;
                        }
                    case "double[]"://新添加，原来无此类型
                    case "Double[]"://新添加，原来无此类型
                        {
                            int intTemp = GetArrayLengthByAttribute(fi);
                            length += intTemp * 8;
                            break;
                        }
                    default:
                        {
                            //其它的结构体类型
                            if (!fieldType.IsPrimitive)
                            {
                                if (fieldType.HasElementType)
                                {
                                    int intTemp = GetArrayLengthByAttribute(fi);
                                    length += intTemp * GetStructLength(fieldType.GetElementType());
                                }
                                else
                                {
                                    length += GetStructLength(fieldType);
                                }
                            }
                            else
                            {
                                Debug.LogError(" 获取类型的长度错误！！  type.Name:" + type.Name + "  fieldType.Name:" + fieldType.Name);
                                length += 0;
                            }
                            break;
                        }
                }
            }
            if (!DicStructLength.ContainsKey(type.FullName))
            {
                DicStructLength.Add(type.FullName, length);
            }
            return length;
        }

        //根据属性获取数组的长度
        private static int GetArrayLengthByAttribute(MemberInfo mi)
        {
            int length = 0;
            ProtoAttribute proto = mi.GetCustomAttribute<ProtoAttribute>();
            if (proto!=null)
            {

                if (proto.unmanagedType== UnmanagedType.ByValArray)
                {
                    length = proto.SizeConst;
                }
            }
            
           
            //Attribute[] attrs = Attribute.GetCustomAttributes(mi);
            //int length = 0;
            //for (int i = 0; i < attrs.Length; i++)
            //{
            //    if (attrs[i].GetType() == typeof(MyTypeAttribute))
            //    {
            //        length = ((MyTypeAttribute)attrs[i]).Pet;
            //        break;
            //    }
            //}
            return length;
        }
        /// <summary>
        /// 处理json
        /// </summary>
        /// <param name="json">json字符串</param>
        /// <returns></returns>
        public static Hashtable JsonToHashTable(string json)
        {
            Hashtable ht = new Hashtable();
            string jsonStr = json.Substring(1, json.Length - 2); //去掉首尾{}
            jsonStr = jsonStr.Replace("\"", "").Replace("'", "").Replace(" ", ""); //去掉所有" '
            string[] jsonArr = SplitJson(jsonStr, ",");
            string str = null;

            for (int i = 0; i < jsonArr.Length; i++)
            {
                str = jsonArr[i];
                string[] arr = SplitJson(str, ":");
                //判断是否包含[ ]
                if (arr[1].Contains("[")) //做数组处理
                {
                    List<Hashtable> subHtl = JsonToHashTableList(arr[1]);
                    ht.Add(arr[0], subHtl);
                }
                else if (arr[1].Contains("{")) //做json处理
                {
                    Hashtable subHt = JsonToHashTable(arr[1]);
                    ht.Add(arr[0], subHt);
                }
                else
                {
                    ht.Add(arr[0], arr[1]);
                }
            }

            return ht;
        }

        /// <summary>
        /// 处理json数组
        /// </summary>
        /// <param name="json">json数组字符串</param>
        /// <returns></returns>
        public static List<Hashtable> JsonToHashTableList(string json)
        {
            List<Hashtable> htl = new List<Hashtable>();
            string jsonStr = json.Substring(1, json.Length - 2); //去掉首尾[]
            string[] jsonArr = SplitJson(jsonStr, ",");
            for (int j = 0; j < jsonArr.Length; j++)
            {
                Hashtable ht = JsonToHashTable(jsonArr[j]);
                htl.Add(ht);
            }

            return htl;
        }
        //设置结构数组的值
        private static object GetStructValue<T>(int arrayLength, Type elementType, ref int start, byte[] receiveData) where T : struct
        {
            int structLength = GetStructLength(elementType);
            T[] objValues = new T[arrayLength];
            for (int j = 0; j < arrayLength; j++)
            {
                byte[] structData = new byte[structLength];
                Array.Copy(receiveData, start, structData, 0, structLength);
                objValues[j] = (T)bytesToStruct(structData, elementType);
                start += structLength;
            }
            return objValues;
        }
        /// <summary>
        /// 依据传入的符号分割字符串
        /// </summary>
        /// <param name="json"></param>
        /// <param name="code">冒号则只分割一次，逗号无视[],{}中的逗号分割</param>
        /// <returns></returns>
        private static string[] SplitJson(string json, string code)
        {
            List<string> res = new List<string>();
            if (code == ",")
            {
                //无视[],{}中的逗号分割
                string pattern = @"(?<=\{|\[.*),(?=.*\}|\])";
                string result = Regex.Replace(json, pattern, "####"); //把[ ]和{ }中的逗号排除
                string[] arr = result.Split(',');
                string temp = null;
                for (int i = 0; i < arr.Length; i++)
                {
                    temp = arr[i].Replace("####", ","); //恢复[ ]和{ }中的逗号
                    res.Add(temp);
                }
            }
            else if (code == ":")
            {
                //冒号则只分割一次
                int index = json.IndexOf(code);
                res.Add(json.Substring(0, index));
                res.Add(json.Substring(index + 1, json.Length - index - 1));
            }

            return res.ToArray();
        }
    }
}